# Performs generic (non-project specific) validation of v1 Snippet File Contents

include(${CMAKE_CURRENT_LIST_DIR}/json.cmake)

function(snippet_has_fields snippet contents)
  get_filename_component(filename "${snippet}" NAME)
  json_has_key("${snippet}" "${contents}" role)
  json_has_key("${snippet}" "${contents}" result)
  json_has_key("${snippet}" "${contents}" workingDir)
  if (NOT filename MATCHES "^build-*")
    json_has_key("${snippet}" "${contents}" command)
  endif()
  if (filename MATCHES "^link-*")
    json_has_key("${snippet}" "${contents}" target)
    json_has_key("${snippet}" "${contents}" outputs)
    json_has_key("${snippet}" "${contents}" outputSizes)
    json_has_key("${snippet}" "${contents}" targetType)
    json_has_key("${snippet}" "${contents}" targetLabels)
    json_has_key("${snippet}" "${contents}" config)
  elseif (filename MATCHES "^compile-*")
    json_has_key("${snippet}" "${contents}" target)
    json_has_key("${snippet}" "${contents}" outputs)
    json_has_key("${snippet}" "${contents}" outputSizes)
    json_has_key("${snippet}" "${contents}" source)
    json_has_key("${snippet}" "${contents}" language)
    json_has_key("${snippet}" "${contents}" config)
  elseif (filename MATCHES "^custom-*")
    json_has_key("${snippet}" "${contents}" outputs)
    json_has_key("${snippet}" "${contents}" outputSizes)
  elseif (filename MATCHES "^test-*")
    json_has_key("${snippet}" "${contents}" testName)
    json_has_key("${snippet}" "${contents}" config)
  endif()
  if(ARGS_DYNAMIC_QUERY)
    json_has_key("${snippet}" "${contents}" dynamicSystemInformation)
    string(JSON dynamicSystemInfo ERROR_VARIABLE noInfo GET "${contents}" dynamicSystemInformation)
    if (noInfo MATCHES NOTFOUND)
      json_has_key("${snippet}" ${dynamicSystemInfo} beforeCPULoadAverage)
      json_has_key("${snippet}" ${dynamicSystemInfo} beforeHostMemoryUsed)
      json_has_key("${snippet}" ${dynamicSystemInfo} beforeCPULoadAverage)
      json_has_key("${snippet}" ${dynamicSystemInfo} beforeHostMemoryUsed)
    endif()
  else()
    json_missing_key("${snippet}" "${contents}" dynamicSystemInformation)
    string(JSON dynamicSystemInfo ERROR_VARIABLE noInfo GET "${contents}" dynamicSystemInformation)
    if (noInfo MATCHES NOTFOUND)
      json_missing_key("${snippet}" ${dynamicSystemInfo} beforeCPULoadAverage)
      json_missing_key("${snippet}" ${dynamicSystemInfo} beforeHostMemoryUsed)
      json_missing_key("${snippet}" ${dynamicSystemInfo} beforeCPULoadAverage)
      json_missing_key("${snippet}" ${dynamicSystemInfo} beforeHostMemoryUsed)
    endif()
  endif()
  return(PROPAGATE RunCMake_TEST_FAILED ERROR_MESSAGE)
endfunction()

function(snippet_valid_timing contents)
  string(JSON start GET "${contents}" timeStart)
  string(JSON duration GET "${contents}" duration)
  if (start LESS 0)
    snippet_error("${snippet}" "Negative time start: ${start}")
  endif()
  if (duration LESS 0)
    json_error("${snippet}" "Negative duration: ${end}")
  endif()
  return(PROPAGATE RunCMake_TEST_FAILED ERROR_MESSAGE)
endfunction()

function(verify_snippet_data snippet contents)
  snippet_has_fields("${snippet}" "${contents}")
  snippet_valid_timing("${contents}")
  string(JSON version GET "${contents}" version)
  if (NOT version EQUAL 1)
    json_error("${snippet}" "Version must be 1, got: ${version}")
  endif()
  string(JSON outputs ERROR_VARIABLE noOutputs GET "${contents}" outputs)
  if (NOT outputs MATCHES NOTFOUND)
    string(JSON outputSizes ERROR_VARIABLE noOutputSizes GET "${contents}" outputSizes)
    list(LENGTH outputs outputsLen)
    list(LENGTH outputSizes outputSizesLen)
    if (outputSizes MATCHES NOTFOUND OR NOT outputsLen EQUAL outputSizesLen)
      json_error("${snippet}" "outputs and outputSizes do not match")
    endif()
  endif()
  return(PROPAGATE ERROR_MESSAGE RunCMake_TEST_FAILED role)
endfunction()

function(verify_snippet_file snippet contents)
  verify_snippet_data("${snippet}" "${contents}")

  string(JSON role GET "${contents}" role)
  get_filename_component(filename "${snippet}" NAME)
  if (NOT filename MATCHES "^${role}-")
    json_error("${snippet}" "Role \"${role}\" doesn't match snippet filename")
  endif()

  return(PROPAGATE ERROR_MESSAGE RunCMake_TEST_FAILED role)
endfunction()
